#pragma once
#include "OptionTag.h"
#include "GetPyType.h"
#include <assert.h>
#include "ProUtil.h"

namespace pyBind{

	struct nullTag{};


	 /*
	template<typename Protktype, typename pytype>
	struct ArgTuple_TTTT{
		typedef Protktype Protktype;
		typedef pytype pytype;

		

		Protktype m_protkval;
		pytype	pyval;

		int self_to_this(PyObject *self){}

		char* PyArgStr(){return "o";}
		int PyValueToTkValue(){}


		int TKValueToPyValue(){}
	};*/





	//struct ProArrayTag{};	// ProArray


	template<typename Tuple,int argpasstypeMask = _val>
	struct GetTkCallTypeTT
	{
		typedef typename Tuple::Protktype type;
		static type GetVal(Tuple& val)
		{
			return val.GetVal();
		}
	};
	template<typename Tuple>
	struct GetTkCallTypeTT<Tuple,_adr>
	{
		typedef typename Tuple::ProtkPointType type;
		static type GetVal(Tuple& val)
		{
			 return val.GetValPoint();
		}
	};

	template<typename Tuple>
	struct GetTkCallTypeT:GetTkCallTypeTT<Tuple,Tuple::ArgTagval&_adr>
	{
	};






};//end of namespace  pyBind

namespace pyBind{

	struct WStringTag
	{
		typedef wchar_t* Protktype;
		typedef wchar_t* ProtkPointType;
		typedef PyObject* pytype;

		Protktype m_protkval;
		pytype pyval;
		pytype pyRetval;

		WStringTag():m_protkval(0){}
		virtual ~WStringTag(){delete[] m_protkval;}

		ProtkPointType GetValPoint()
		{
			return m_protkval;
		}
		Protktype GetVal()
		{
			return m_protkval;
		}

		int self_to_this(PyObject *self)
		{
			assert(0);
			return 0;
		}

		static char* PyArgStr(){return "U";}
		int PyValueToTkValue()
		{
			int size = PyUnicode_GET_SIZE(pyval);
			wchar_t* valstr = PyUnicode_AS_UNICODE(pyval);
			m_protkval = new wchar_t[size+1];
			return wcscpy_s(m_protkval,size+1,valstr);
		}

		static char* PyTkStr(){return "u";}
		int TkValueToPyValue(){
			pyRetval = Py_BuildValue("u",m_protkval);
			return 0; 
		}

	};

	struct StringTag
	{
		typedef char* Protktype;
		typedef char* ProtkPointType;
		typedef PyObject* pytype;

		Protktype m_protkval;
		pytype pyval;
		pytype pyRetval;

		StringTag():m_protkval(0){}
		virtual ~StringTag(){delete[] m_protkval;}

		ProtkPointType GetValPoint()
		{
			return m_protkval;
		}
		Protktype GetVal()
		{
			return m_protkval;
		}

		int self_to_this(PyObject *self)
		{
			assert(0);
			return 0;
		}

		static char* PyArgStr(){return "U";}
		int PyValueToTkValue()
		{
			PyObject*ASCIIobj = PyUnicode_AsASCIIString(pyval);
			int size = PyUnicode_GET_SIZE(ASCIIobj);
			char* valstr = PyBytes_AsString(ASCIIobj);
			m_protkval = new char[size+1];
			 strcpy_s(m_protkval,size+1,valstr);
			Py_XDECREF(ASCIIobj); 
			return 1;
		}

		static char* PyTkStr(){return "u";}
		int TkValueToPyValue(){
			pyRetval = Py_BuildValue("u",m_protkval);
			return 0; 
		}

	};

	struct ProStringTag
	{
		typedef char* Protktype;
		typedef char** ProtkPointType;
		typedef PyObject* pytype;

		Protktype m_protkval;
		pytype pyval;
		pytype pyRetval;

		ProStringTag():m_protkval(0){}
		virtual ~ProStringTag(){ProStringFree(m_protkval);}

		ProtkPointType GetValPoint()
		{
			return &m_protkval;
		}
		Protktype GetVal()
		{
			return m_protkval;
		}

		int self_to_this(PyObject *self)
		{
			assert(0);
			return 0;
		}

		static char* PyArgStr(){return "U";}
		int PyValueToTkValue()
		{
			assert(0);
			return 0;
		}

		static char* PyTkStr(){return "u";}
		int TkValueToPyValue(){
			pyRetval = Py_BuildValue("u",m_protkval);
			return 0; 
		}

	};

	struct ProNameTag
	{
		typedef wchar_t* Protktype;
		typedef wchar_t* ProtkPointType;
		typedef PyObject* pytype;

		ProName m_protkval;
		pytype pyval;
		pytype pyRetval;

		wchar_t* GetValPoint()
		{
			return m_protkval;
		}
		wchar_t* GetVal()
		{
			return m_protkval;
		}

		int self_to_this(PyObject *self)
		{
			assert(0);
			return 0;
		}

		static char* PyArgStr(){return "U";}
		int PyValueToTkValue()
		{
			wchar_t* valstr = PyUnicode_AS_UNICODE(pyval);
			return wcscpy_s(m_protkval,32,valstr);
		}

		static char* PyTkStr(){return "u";}
		int TkValueToPyValue(){
			pyRetval = Py_BuildValue("u",m_protkval);
			return 0; 
		}

	};

};//end of namespace  pyBind

namespace pyBind{

	struct ProArrayTag{};

	/*
	template<typename TEle>
	struct ProArrayTag
	{
		typedef wchar_t* Protktype;
		typedef wchar_t* ProtkPointType;
		typedef PyObject* pytype;

		ProName m_protkval;
		pytype pyval;
		pytype pyRetval;

		wchar_t* GetValPoint()
		{
			return m_protkval;
		}
		wchar_t* GetVal()
		{
			return m_protkval;
		}

		int self_to_this(PyObject *self)
		{
			assert(0);
			return 0;
		}

		static char* PyArgStr(){return "U";}
		int PyValueToTkValue()
		{
			wchar_t* valstr = PyUnicode_AS_UNICODE(pyval);
			return wcscpy_s(m_protkval,31,valstr);
		}

		static char* PyTkStr(){return "u";}
		int TkValueToPyValue(){
			pyRetval = Py_BuildValue("u",m_protkval);
			return 0; 
		}

	};
	*/

};//end of namespace  pyBind



